import { defineStore } from "pinia";
import { getToken, removeToken, setToken } from "../utils/token-utils";
import type { UserInfoState } from "./interface";
import { ElMessage } from "element-plus";
import { staticRoutes, allAsyncRoutes, anyRoutes } from "@/router/routes";
import { loginApi, getUserInfoApi, logoutApi } from "@/api/acl/login";
import type { RouteRecordRaw } from "vue-router";
import router from "@/router";
import cloneDeep from "lodash/cloneDeep";

function filterAsyncRoutes(
  allAsyncRoutes: Array<RouteRecordRaw>,
  routes: string[]
) {
  return allAsyncRoutes.filter((route) => {
    if (routes.includes(route.name as string)) {
      if (route.children && route.children.length) {
        const childrenRoutes = filterAsyncRoutes(route.children, routes);
        // 修改了原数据
        route.children = childrenRoutes;
        // const childrenRoutes = route.children.filter((route) => {
        //   if (routes.includes(route.name)) {
        //     return true;
        //   }
        //   return false;
        // });
        // route.children = childrenRoutes;
      }
      return true;
    }
    return false;
  });
}

function addRoutes(routes: Array<RouteRecordRaw>) {
  routes.forEach((route) => {
    router.addRoute(route);
  });
}

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore("userInfo", {
  state: (): UserInfoState => ({
    // 数据初始化要从localStorage取出数据使用
    // 保证刷新页面，pinia中token还在
    token: getToken() as string,
    name: "",
    avatar: "",
    buttons: [],
    routes: [],
    menuRoutes: [],
  }),

  actions: {
    // 登录
    async login(username: string, password: string) {
      // 请求登录，得到token
      const { token } = await loginApi(username, password);
      // 存起来 - 保证刷新数据还在 localStorage
      setToken(token); // 将数据存储在localStorage中（存在硬盘中，读写更慢）
      this.token = token; // 将数据存储在pinia中（存在内存中，读写更快）
      // 真实需求：除了登录接口其他接口都需要token参数
    },

    // 获取用户数据
    async getInfo() {
      const res = await getUserInfoApi();

      // 动态路由表，通过用户路由权限值进行遍历过滤，保留用户拥有访问权限的路由表
      const filterRoutes = filterAsyncRoutes(
        cloneDeep(allAsyncRoutes),
        res.routes
      );
      // 将用户拥有访问权限的路由表动态添加路由中，让其生效，此时用户才能访问
      addRoutes([...filterRoutes, ...anyRoutes]);

      // 将用户数据存储起来 pinia
      this.name = res.name;
      this.avatar = res.avatar;
      this.routes = res.routes;
      this.buttons = res.buttons;
      // 左侧菜单读取数据进行遍历生成菜单
      this.menuRoutes = [...staticRoutes, ...filterRoutes];
    },

    async logout() {
      await logoutApi();
    },

    reset() {
      // 删除localStorage中保存的token
      removeToken();
      // 提交重置用户信息的mutation
      this.token = "";
      this.name = "";
      this.avatar = "";
      this.routes = [];
      this.buttons = [];
      this.menuRoutes = [];
    },
  },
});
